﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Spanner
{
    public partial class UI
    {
        // These functions correspond one-to-one with their JavaScript counterparts.

        /// <summary>
        /// Treat an int quantity as a double -- in JavaScript this is the identity function.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Expr<double> ToDouble(Expr<int> x)
        {
            return JSExpr<double>("#", x);
        }
        /// <summary>
        /// Treat an int array as a double array -- in JavaScript this is the identity function.
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Expr<double[]> ToDoubles(Expr<int[]> x)
        {
            return JSExpr<double[]>("#", x);
        }

        public static Expr<double> NaNDouble()
        {
            return JSExpr<double>("NaN");
        }

        public static Expr<int> NaNInt()
        {
            return JSExpr<int>("NaN");
        }

        public static Expr<double> InfinityDouble()
        {
            return JSExpr<double>("Infinity");
        }

        public static Expr<int> InfinityInt()
        {
            return JSExpr<int>("Infinity");
        }

        public static Expr<bool> IsFinite(Expr<double> x)
        {
            return JSExpr<bool>("isFinite(#)", x);
        }

        public static Expr<bool> IsFinite(Expr<int> x)
        {
            return JSExpr<bool>("isFinite(#)", x);
        }

        public static Expr<bool> IsNaN(Expr<double> x)
        {
            return JSExpr<bool>("isNaN(#)", x);
        }

        public static Expr<bool> IsNaN(Expr<int> x)
        {
            return JSExpr<bool>("isNaN(#)", x);
        }

        public static Expr<double> ParseDouble(Expr<string> x)
        {
            return ParseFloat(x);
        }

        public static Expr<double> ParseFloat(Expr<string> x)
        {
            return JSExpr<double>("parseFloat(#)", x);
        }

        public static Expr<int> ParseInt(Expr<string> x, Expr<int> radix = null)
        {
            return ( ((object)radix) == null
                   ? JSExpr<int>("parseInt(#)", x)
                   : JSExpr<int>("parseInt(#, #)", x, radix)
                   );
        }

        public static Expr<string> ToExponential(Expr<double> x, Expr<int> numFracDigits = null)
        {
            return ( ((object)numFracDigits) == null
                   ? JSExpr<string>("#.toExponential()", x)
                   : JSExpr<string>("#.toExponential(#)", x, numFracDigits)
                   );
        }

        public static Expr<string> ToFixed(Expr<double> x, Expr<int> numFracDigits = null)
        {
            return ( ((object)numFracDigits) == null
                   ? JSExpr<string>("#.toFixed()", x)
                   : JSExpr<string>("#.toFixed(#)", x, numFracDigits)
                   );
        }

        public static Expr<string> ToPrecision(Expr<double> x, Expr<int> numPrecDigits = null)
        {
            return ( ((object)numPrecDigits) == null
                   ? JSExpr<string>("#.toPrecision()", x)
                   : JSExpr<string>("#.toPrecision(#)", x, numPrecDigits)
                   );
        }

        public static Expr<string> ToLocaleString(Expr<double> x)
        {
            return JSExpr<string>("#.toLocaleString()", x);
        }
    }
}